home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 6 / FM Towns Free Software Collection 6.iso / t_os / chtiff / source / chtiff4.c < prev    next >
C/C++ Source or Header  |  1993-07-08  |  4KB  |  210 lines

  1. /* LZW圧縮法による、TIFF画像データ処理部 */
  2.  
  3. #include<stdio.h>
  4. #include<stdlib.h>
  5. #define COMPRESS_SECTION 1
  6. #include"define.h"
  7. #include"function.h"
  8.  
  9. #define CLEAR_CODE 256
  10. #define EOF_CODE 257
  11. #define MAXTABLE 4096
  12.  
  13. unsigned int header[ MAXTABLE ];
  14. unsigned int table_next[ MAXTABLE ];
  15. unsigned short table_ch[ MAXTABLE ];
  16. unsigned int table_high[ MAXTABLE ];
  17. unsigned int table_low[ MAXTABLE ];
  18.  
  19. unsigned int cbl;
  20. unsigned int table_ix;
  21.  
  22. unsigned int add_with;
  23.  
  24. unsigned char *add;
  25. unsigned long uncomp_bytes;
  26.  
  27.  
  28. void init_table(void)
  29. {
  30.     int i;
  31.  
  32.     putchar('>');
  33.  
  34.     for(i=0; i<256; i++){
  35.         table_ch[i] = i;
  36.         table_next[i] = table_high[i] = table_low[i] = MAXTABLE+1;
  37.         }
  38.  
  39.     for(i=0; i<MAXTABLE; i++){
  40.         header[i] = MAXTABLE+1;
  41.         }
  42. }
  43.  
  44.  
  45. int tsearch(int s, int c)
  46. {
  47.     int stp;    /* search table pointer */
  48.  
  49.     if( s == MAXTABLE+1 ) return( c );
  50.  
  51.     stp = header[s];    /* 末尾のNEXTがsであるやつの集まり */
  52.  
  53.     LOOP:
  54.     if( stp == MAXTABLE+1 ){
  55.         return(MAXTABLE+1);
  56.         }
  57.  
  58.     if( table_ch[ stp ] == c ){
  59.         return( stp );
  60.         }
  61.  
  62.     add_with = stp;
  63.  
  64.     if( table_ch[ stp ] < c ){
  65.         stp = table_high[stp];
  66.         goto LOOP;
  67.         }
  68.  
  69.     stp = table_low[stp];
  70.     goto LOOP;
  71. }
  72.  
  73.  
  74. void add_entry(int s, int c)
  75. {
  76.     /*
  77.     s: コード番号を差す。コードのにcを付け足したのがs:cであり、
  78.     そいつのコード番号はtable_ixである。
  79.     */
  80.  
  81.     table_next[ table_ix ] = s;
  82.     table_ch[ table_ix ] = c;
  83.  
  84.     /* 以後検索のための設定 */
  85.     table_high[ table_ix ] = table_low[ table_ix ] = MAXTABLE+1;
  86.  
  87.     if( header[s] == MAXTABLE+1 ){
  88.         header[s] = table_ix;
  89.         table_ix++;
  90.         return;
  91.         }
  92.  
  93.     if( c > table_ch[ add_with ] ){
  94.         table_high[ add_with ] = table_ix;
  95.         table_ix++;
  96.         return;
  97.         }
  98.  
  99.     table_low[add_with] = table_ix;
  100.     table_ix++;
  101.     return;
  102. }
  103.  
  104.  
  105. void put_code(short ch)
  106. {
  107.     unsigned static long a = 0;    /* ビット操作作業用 */
  108.     unsigned static int PackedBits = 0;    /* aに入っている有効ビット数 */
  109.     unsigned static char start_add[4100], *pc;
  110.     unsigned static long stack_bytes = 0, put_bytes = 0;
  111.     static short mask_table[4] = {0x1ff, 0x3ff, 0x7ff, 0xfff};
  112.     static int INIT = 0;
  113.     unsigned long chl;    /* ch of long bytes */
  114.  
  115.     if(INIT==0){
  116.         pc = start_add;
  117.         put_bytes = stack_bytes = PackedBits = a = 0;
  118.         INIT=1;
  119.         }
  120.  
  121.     chl = ch & mask_table[cbl-9];    /* 念のため不要ビットはマスク */
  122.     a <<= cbl;
  123.     a |= chl;
  124.     PackedBits += cbl-8; /* ここでは、8ビット以上が何ビットかを表わす */
  125.  
  126.     /* 必ず1バイトは出力するはず(嗚呼、コンパイラー依存)*/
  127.     *pc = (a >> PackedBits);
  128.     pc++;
  129.     stack_bytes++;
  130.     put_bytes++;
  131.  
  132.     if(PackedBits >= 8){
  133.         PackedBits -= 8;
  134.         *pc = (a >> PackedBits) & 0xff;
  135.         pc++;
  136.         stack_bytes++;
  137.         put_bytes++;
  138.         }
  139.  
  140.     if( stack_bytes >= 4095 ){
  141.         fwrite(start_add, stack_bytes, 1, to.fp);
  142.         pc = start_add;
  143.         stack_bytes = 0;
  144.         }
  145.  
  146.     if(ch != EOF_CODE) return;
  147.  
  148.     put_bytes += 2;
  149.     printf(" write %lu bytes\n",put_bytes );
  150.  
  151.     *(to.Strips_ByteCount + to.Strips) = put_bytes;
  152.     *pc = (a << (8-PackedBits)) & 0xff;
  153.     stack_bytes += 2;
  154.     fwrite(start_add, stack_bytes , 1, to.fp);
  155.     INIT = 0;
  156.  
  157.     return;
  158. }
  159.  
  160.  
  161. void compress(unsigned char *a, unsigned long b)
  162. {
  163.     unsigned short s,p;
  164.     unsigned short ch;
  165.  
  166.     add = a;
  167.     uncomp_bytes = b;
  168.     
  169.     printf("Compress %lu bytes ", uncomp_bytes);
  170.  
  171.     init_table();
  172.     cbl=9;
  173.     table_ix = EOF_CODE + 1;
  174.     put_code( CLEAR_CODE );
  175.  
  176.     s = MAXTABLE+1;
  177.     while( uncomp_bytes ){
  178.         ch = *add;
  179.         add++;
  180.         uncomp_bytes--;
  181.  
  182.         /* S:Cがテーブル内に存在するか? */
  183.         if( (p = tsearch(s, ch)) != MAXTABLE+1 ){
  184.             s = p;    /* S <- S:C */
  185.             }
  186.         else{
  187.             /* Sのインデックスを出力 */
  188.             put_code(s);
  189.             if( table_ix < MAXTABLE-2 ){
  190.                 /* S:Cをテーブルに登録 */
  191.                 add_entry(s, ch);
  192.                 if( table_ix == (1<<cbl) ) cbl++;
  193.                 }
  194.             else{
  195.                 /* クリアコード出力 */
  196.                 put_code( CLEAR_CODE );
  197.                 init_table();
  198.                 cbl = 9;
  199.                 table_ix = EOF_CODE+1;
  200.                 }
  201.  
  202.             /* S <- C */
  203.             s = ch;
  204.             }
  205.         }
  206.     /* Sのインデックスを出力 */
  207.     put_code( s );
  208.     put_code( EOF_CODE );
  209. }
  210.